import { 
  Controller, 
  Post, 
  Get, 
  Body, 
  Headers,
  Req,
  Query,
  Param,
  Logger,
  BadRequestException
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Request } from 'express';
import { EnhancedForwardingService } from '../services/enhanced-forwarding.service';
import { ApiProvider, TargetProvider } from '../interfaces/api-adapter.interface';
import { 
  GeminiGenerateContentRequest,
  GeminiGenerateContentResponse,
  GeminiListModelsResponse,
  GeminiCountTokensRequest,
  GeminiCountTokensResponse
} from '../dto/gemini.dto';

/**
 * Google Gemini API 兼容控制器
 * 提供完整的 Gemini API 接口，通过适配器转发到 Copilot
 */
@ApiTags('Gemini API Compatible')
@Controller('gemini/v1')
export class GeminiProxyController {
  private readonly logger = new Logger(GeminiProxyController.name);

  constructor(private readonly enhancedForwarding: EnhancedForwardingService) {}

  /**
   * Gemini Generate Content API
   * 生成文本内容的核心接口
   */
  @Post('models/:model/generateContent')
  @ApiOperation({ 
    summary: 'Generate Content (Gemini Compatible)',
    description: 'Generates a response from the model given an input GenerateContentRequest.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Content generated successfully',
    type: GeminiGenerateContentResponse
  })
  @ApiResponse({ 
    status: 400, 
    description: 'Invalid request parameters'
  })
  @ApiResponse({ 
    status: 401, 
    description: 'Invalid authentication'
  })
  async generateContent(
    @Param('model') model: string,
    @Body() request: GeminiGenerateContentRequest,
    @Headers() headers: Record<string, string>,
    @Req() req: Request
  ): Promise<GeminiGenerateContentResponse> {
    try {
      this.logger.log(`Gemini generateContent request: model=${model}, contents=${request.contents?.length || 0}`);
      
      // 验证请求参数
      if (!model) {
        throw new BadRequestException('Model parameter is required');
      }
      
      if (!request.contents || request.contents.length === 0) {
        throw new BadRequestException('Contents array cannot be empty');
      }

      const requestInfo = {
        headers,
        ip: req.ip,
        userAgent: req.get('User-Agent'),
        endpoint: 'generateContent',
        model
      };

      // 使用增强转发服务，通过 Gemini 适配器转发到 Copilot
      const result = await this.enhancedForwarding.forwardApiRequest(
        ApiProvider.GEMINI,
        TargetProvider.COPILOT,
        { ...request, model },
        requestInfo
      );

      return result;
    } catch (error) {
      this.logger.error(`Gemini generateContent failed: ${error.message}`);
      throw error;
    }
  }

  /**
   * Gemini Stream Generate Content API
   * 流式生成内容接口
   */
  @Post('models/:model/streamGenerateContent')
  @ApiOperation({ 
    summary: 'Stream Generate Content (Gemini Compatible)',
    description: 'Generates a streamed response from the model given an input GenerateContentRequest.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Content stream started successfully'
  })
  async streamGenerateContent(
    @Param('model') model: string,
    @Body() request: GeminiGenerateContentRequest,
    @Headers() headers: Record<string, string>,
    @Req() req: Request
  ) {
    try {
      this.logger.log(`Gemini streamGenerateContent request: model=${model}`);
      
      if (!model) {
        throw new BadRequestException('Model parameter is required');
      }
      
      if (!request.contents || request.contents.length === 0) {
        throw new BadRequestException('Contents array cannot be empty');
      }

      const requestInfo = {
        headers,
        ip: req.ip,
        userAgent: req.get('User-Agent'),
        endpoint: 'streamGenerateContent',
        model
      };

      // 使用增强转发服务转发流式请求
      const result = await this.enhancedForwarding.forwardApiRequest(
        ApiProvider.GEMINI,
        TargetProvider.COPILOT,
        { ...request, model, stream: true },
        requestInfo
      );

      return result;
    } catch (error) {
      this.logger.error(`Gemini streamGenerateContent failed: ${error.message}`);
      throw error;
    }
  }

  /**
   * Gemini Count Tokens API
   * 计算输入内容的token数量
   */
  @Post('models/:model/countTokens')
  @ApiOperation({ 
    summary: 'Count Tokens (Gemini Compatible)',
    description: 'Runs a model\'s tokenizer on input text and returns the token count.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Tokens counted successfully',
    type: GeminiCountTokensResponse
  })
  async countTokens(
    @Param('model') model: string,
    @Body() request: GeminiCountTokensRequest,
    @Headers() headers: Record<string, string>,
    @Req() req: Request
  ): Promise<GeminiCountTokensResponse> {
    try {
      this.logger.log(`Gemini countTokens request: model=${model}`);
      
      if (!model) {
        throw new BadRequestException('Model parameter is required');
      }
      
      if (!request.contents || request.contents.length === 0) {
        throw new BadRequestException('Contents array cannot be empty');
      }

      const requestInfo = {
        headers,
        ip: req.ip,
        userAgent: req.get('User-Agent'),
        endpoint: 'countTokens',
        model
      };

      // 使用增强转发服务转发token计数请求
      const result = await this.enhancedForwarding.forwardApiRequest(
        ApiProvider.GEMINI,
        TargetProvider.COPILOT,
        { ...request, model },
        requestInfo
      );

      return result;
    } catch (error) {
      this.logger.error(`Gemini countTokens failed: ${error.message}`);
      throw error;
    }
  }

  /**
   * Gemini List Models API
   * 获取可用模型列表
   */
  @Get('models')
  @ApiOperation({ 
    summary: 'List Models (Gemini Compatible)',
    description: 'Lists models available through the API.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Models listed successfully',
    type: GeminiListModelsResponse
  })
  async listModels(
    @Headers() headers: Record<string, string>,
    @Query('pageSize') pageSize?: number,
    @Query('pageToken') pageToken?: string
  ): Promise<GeminiListModelsResponse> {
    this.logger.log('Gemini models list request');
    
    return {
      models: [
        {
          name: "models/gemini-1.5-flash",
          displayName: "Gemini 1.5 Flash",
          description: "Fast and versatile performance across a diverse variety of tasks",
          inputTokenLimit: 1048576,
          outputTokenLimit: 8192,
          supportedGenerationMethods: ["generateContent", "countTokens"],
          temperature: 1.0,
          topP: 0.95,
          topK: 40
        },
        {
          name: "models/gemini-1.5-flash-8b",
          displayName: "Gemini 1.5 Flash-8B",
          description: "High volume and lower intelligence tasks",
          inputTokenLimit: 1048576,
          outputTokenLimit: 8192,
          supportedGenerationMethods: ["generateContent", "countTokens"],
          temperature: 1.0,
          topP: 0.95,
          topK: 40
        },
        {
          name: "models/gemini-1.5-pro",
          displayName: "Gemini 1.5 Pro",
          description: "Mid-size multimodal model that supports up to 2 million tokens",
          inputTokenLimit: 2097152,
          outputTokenLimit: 8192,
          supportedGenerationMethods: ["generateContent", "countTokens"],
          temperature: 1.0,
          topP: 0.95,
          topK: 40
        },
        {
          name: "models/gemini-pro",
          displayName: "Gemini Pro",
          description: "Best performance for text-only prompts",
          inputTokenLimit: 32768,
          outputTokenLimit: 8192,
          supportedGenerationMethods: ["generateContent", "countTokens"],
          temperature: 0.9,
          topP: 1.0,
          topK: 32
        },
        {
          name: "models/gemini-pro-vision",
          displayName: "Gemini Pro Vision",
          description: "Best performance for prompts containing both text and images",
          inputTokenLimit: 16384,
          outputTokenLimit: 2048,
          supportedGenerationMethods: ["generateContent", "countTokens"]
        }
      ],
      nextPageToken: pageToken ? undefined : "next_page_token_example"
    };
  }

  /**
   * Gemini Get Model API
   * 获取特定模型的详细信息
   */
  @Get('models/:model')
  @ApiOperation({ 
    summary: 'Get Model (Gemini Compatible)',
    description: 'Gets information about a specific Model.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Model information retrieved successfully'
  })
  @ApiResponse({ 
    status: 404, 
    description: 'Model not found'
  })
  async getModel(
    @Param('model') model: string,
    @Headers() headers: Record<string, string>
  ) {
    this.logger.log(`Gemini get model request: ${model}`);
    
    // 简化的模型信息，实际应该从适配器获取
    const modelInfo = {
      name: model,
      displayName: model.replace('models/', '').replace('-', ' ').replace(/\b\w/g, l => l.toUpperCase()),
      description: "AI model for text generation and analysis",
      inputTokenLimit: 32768,
      outputTokenLimit: 8192,
      supportedGenerationMethods: ["generateContent", "countTokens"]
    };

    return modelInfo;
  }

  /**
   * Gemini Batch Embed Contents API (如果支持)
   */
  @Post('models/:model/batchEmbedContents')
  @ApiOperation({ 
    summary: 'Batch Embed Contents (Gemini Compatible)',
    description: 'Generates multiple embeddings from the model given input text in a synchronous call.'
  })
  async batchEmbedContents(
    @Param('model') model: string,
    @Body() request: any,
    @Headers() headers: Record<string, string>,
    @Req() req: Request
  ) {
    try {
      this.logger.log(`Gemini batchEmbedContents request: model=${model}`);
      
      if (!model) {
        throw new BadRequestException('Model parameter is required');
      }

      const requestInfo = {
        headers,
        ip: req.ip,
        userAgent: req.get('User-Agent'),
        endpoint: 'batchEmbedContents',
        model
      };

      // 使用增强转发服务转发嵌入请求
      const result = await this.enhancedForwarding.forwardApiRequest(
        ApiProvider.GEMINI,
        TargetProvider.COPILOT,
        { ...request, model },
        requestInfo
      );

      return result;
    } catch (error) {
      this.logger.error(`Gemini batchEmbedContents failed: ${error.message}`);
      if (error.message.includes('not supported')) {
        throw new BadRequestException('Embeddings not supported by target API');
      }
      throw error;
    }
  }

  /**
   * 获取Gemini API健康状态
   */
  @Get('health')
  @ApiOperation({ 
    summary: 'Gemini API Health Check',
    description: 'Check the health status of Gemini API forwarding'
  })
  async getHealth() {
    this.logger.log('Gemini health check request');
    
    return {
      status: 'healthy',
      timestamp: new Date().toISOString(),
      provider: 'Gemini',
      target: 'Copilot',
      available_endpoints: [
        'POST /gemini/v1/models/{model}/generateContent',
        'POST /gemini/v1/models/{model}/streamGenerateContent',
        'POST /gemini/v1/models/{model}/countTokens',
        'POST /gemini/v1/models/{model}/batchEmbedContents',
        'GET /gemini/v1/models',
        'GET /gemini/v1/models/{model}',
        'GET /gemini/v1/health'
      ]
    };
  }
}